package org.dream.ui.chart.impl;

import java.util.Map;

import org.dream.ui.chart.XAxisModel;

/**
 * X轴模型的实现
 * 
 * @author qiuriyuchen E-mail:panpan_001@126.com
 */
public class XAxisModelImpl extends AxisModelImpl implements XAxisModel {
	private int minValueStadard;// 最小值
	private int maxValueStadard;;// 最大值
	private int minValue;// 最小值
	private int maxValue;// 最大值
	private Map<Integer, String> tickViews;// 刻度显示值从1开始计数
	// 刻度间距，原点刻度是不用的，所以要多算一个,但画的时候左边用半个，右边用半个
	private boolean monthFlag = true;

	public XAxisModelImpl(int minValue, int maxValue, Map<Integer, String> tickViews) {
		this.minValue = minValue;
		this.maxValue = maxValue;
		this.minValueStadard = minValue;
		this.maxValueStadard = maxValue;
		this.tickViews = tickViews;

	}

	public int getXPixelRange() {
		return chartModel.getUseableWidth();
	}

	public int getMaxValueStadard() {
		return maxValueStadard;
	}

	public int getMinValueStadard() {
		return minValueStadard;
	}

	public void move(double zoom) {
		// 如果右，已经是最大值
		if (zoom > 0 && this.maxValue == this.maxValueStadard) {
			return;

		}
		// 如果左，已经是最小值
		if (zoom < 0 && this.minValue == this.minValueStadard) {
			return;

		}
		int moveLen = (int) (this.getRangeValue() * zoom);

		if (zoom < 0) {
			// 左移
			if (moveLen == 0) {
				moveLen = -1;
			}

			int left = this.minValue - this.minValueStadard;
			if (left < Math.abs(moveLen)) {
				moveLen = 0 - left;
			}

		} else {
			// 右移
			if (moveLen == 0) {
				moveLen = 1;
			}
			int right = this.maxValueStadard - this.maxValue;
			if (right < moveLen) {
				moveLen = right;
			}
		}

		this.minValue = this.minValue + moveLen;
		this.maxValue = this.maxValue + moveLen;

	}

	public void zoom(int center, double zoom) {

		int halfLen = (int) (this.getRangeValue() * zoom / 2);
		// 当放大时如果剩下3个后卡死
		if (halfLen * 2 + 1 == this.getRangeValue() && zoom > 1) {
			halfLen += 1;
		}
		//
		if (maxValueStadard <= halfLen * 2) {
			// 两边都不够
			minValue = minValueStadard;
			maxValue = maxValueStadard;

		} else if (center - minValueStadard < halfLen) {
			// 左边不够
			maxValue = minValue + halfLen * 2;

		} else if (maxValue - center < halfLen) {
			// 右边不够
			minValue = maxValue - halfLen * 2;
		} else {
			// 都够
			int midle = (minValue + maxValue) / 2;
			minValue = midle - halfLen;
			maxValue = midle + halfLen;
		}

		// 出错，暂用，有时会超出一
		if (minValue < minValueStadard) {
			minValue = minValueStadard;
		}
		if (maxValue > maxValueStadard) {
			maxValue = maxValueStadard;
		}
	}

	public String getTickDay(int key) {
		return tickViews.get(key);
	}

	public String getTickView(int key) {
		String view = this.getTickDay(key);
		if (this.isOnlyDrawMonth()) {
			view = view.substring(5, 7);
			if (view.substring(0, 1).equals("0")) {
				view = view.replaceAll("0", "");
			}

		}
		return view;

	}

	public double getTickSpacingPixel() {
		return (double) chartModel.getUseableWidth() / (getRangeValue());
	}

	public int translateValueToPx(double value) {
		// 因为原点不用，X轴切分成了( getRangeValue()+1)份，所以差值也得加一，value -
		// minValue+1,minValue不是原点，是原点后的一个点，并入左错了一个
		double screenRangeValue = ((value - minValue + 1) * getTickSpacingPixel());
		return (int) (chartModel.getLeftMargin() + screenRangeValue - this.getTickSpacingPixel() / 2);
	}

	public double translatePxToValue(int screenValue) {
		double trueRange = getRangeValue();
		int screenRange = getXPixelRange();
		double trueValue = (((screenValue - chartModel.getLeftMargin() + this.getTickSpacingPixel() / 2) * trueRange) / screenRange);
		return (int) (trueValue + 1 / 3d + minValue - 1);
	}

	public int getRangeValue() {
		return Math.abs(maxValue - minValue) + 1;
	}

	public int getMaxValue() {
		return maxValue;
	}

	public int getMinValue() {
		return minValue;
	}

	public void setMonthFlag(boolean monthFlag) {
		this.monthFlag = monthFlag;
	}

	public boolean isOnlyDrawMonth() {
		return monthFlag && getRangeValue() > 10;
	}

	public void beforeDraw() {
		// TODO Auto-generated method stub

	}
}
